home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
gnu
/
gprof
/
gpfsrc09.zoo
/
cplusdem.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-02
|
28KB
|
1,394 lines
/* Demangler for GNU C++
Copyright (C) 1989, 1992 Free Software Foundation, Inc.
written by James Clark (jjc@jclark.uucp)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* This is for g++ 1.36.1 (November 6 version). It will probably
require changes for any other version.
Modified for g++ 1.36.2 (November 18 version).
Modified for g++ 1.90.06 (December 31 version).
Modified for g++ 1.95.03 (November 13 verison). */
/* This file exports one function
char *cplus_demangle (const char *name)
If NAME is a mangled function name produced by GNU C++, then
a pointer to a malloced string giving a C++ representation
of the name will be returned; otherwise NULL will be returned.
It is the caller's responsibility to free the string which
is returned.
For example,
cplus_demangle ("_foo__1Ai")
returns
"A::foo(int)"
This file imports xmalloc and xrealloc, which are like malloc and
realloc except that they generate a fatal error if there is no
available memory. */
/* #define nounderscore 1 *//* define this is names don't start with _ */
#include <stdio.h>
#include <ctype.h>
#ifdef USG
#include <memory.h>
#include <string.h>
#else
#include <strings.h>
#define memcpy(s1, s2, n) bcopy ((s2), (s1), (n))
#define memcmp(s1, s2, n) bcmp ((s2), (s1), (n))
#define strchr index
#define strrchr rindex
#endif
/* This is '$' on systems where the assembler can deal with that.
Where the assembler can't, it's '.' (but on many systems '.' is
used for other things). */
#if !defined (CPLUS_MARKER)
#define CPLUS_MARKER '$'
#endif
#ifndef __STDC__
#define const
#endif
#ifdef __STDC__
extern char *cplus_demangle (const char *type);
#else
extern char *cplus_demangle ();
#endif
#ifdef __STDC__
extern char *xmalloc (int);
extern char *xrealloc (char *, int);
extern void free (char *);
#else
extern char *xmalloc ();
extern char *xrealloc ();
extern void free ();
#endif
static char **typevec = 0;
static int ntypes = 0;
static int typevec_size = 0;
static struct {
const char *in;
const char *out;
} optable[] = {
"nw", " new", /* new (1.92, ansi) */
"dl", " delete", /* new (1.92, ansi) */
"new", " new", /* old (1.91) */
"delete", " delete", /* old (1.91) */
"ne", "!=", /* old, ansi */
"eq", "==", /* old, ansi */
"ge", ">=", /* old, ansi */
"gt", ">", /* old, ansi */
"le", "<=", /* old, ansi */
"lt", "<", /* old, ansi */
"plus", "+", /* old */
"pl", "+", /* ansi */
"apl", "+=", /* ansi */
"minus", "-", /* old */
"mi", "-", /* ansi */
"ami", "-=", /* ansi */
"mult", "*", /* old */
"ml", "*", /* ansi */
"aml", "*=", /* ansi */
"convert", "+", /* old (unary +) */
"negate", "-", /* old (unary -) */
"trunc_mod", "%", /* old */
"md", "%", /* ansi */
"amd", "%=", /* ansi */
"trunc_div", "/", /* old */
"dv", "/", /* ansi */
"adv", "/=", /* ansi */
"truth_andif", "&&", /* old */
"aa", "&&", /* ansi */
"truth_orif", "||", /* old */
"oo", "||", /* ansi */
"truth_not", "!", /* old */
"nt", "!", /* ansi */
"postincrement", "++", /* old */
"pp", "++", /* ansi */
"postdecrement", "--", /* old */
"mm", "--", /* ansi */
"bit_ior", "|", /* old */
"or", "|", /* ansi */
"aor", "|=", /* ansi */
"bit_xor", "^", /* old */
"er", "^", /* ansi */
"aer", "^=", /* ansi */
"bit_and", "&", /* old */
"ad", "&", /* ansi */
"aad", "&=", /* ansi */
"bit_not", "~", /* old */
"co", "~", /* ansi */
"call", "()", /* old */
"cl", "()", /* ansi */
"cond", "?:", /* old */
"alshift", "<<", /* old */
"ls", "<<", /* ansi */
"als", "<<=", /* ansi */
"arshift", ">>", /* old */
"rs", ">>", /* ansi */
"ars", ">>=", /* ansi */
"component", "->", /* old */
"rf", "->", /* ansi */
"indirect", "*", /* old */
"method_call", "->()", /* old */
"addr", "&", /* old (unary &) */
"array", "[]", /* old */
"vc", "[]", /* ansi */
"compound", ",", /* old */
"cm", ",", /* ansi */
"nop", "", /* old (for operator=) */
"as", "=", /* ansi */
"cond", "?:", /* old */
"cn", "?:", /* psuedo-ansi */
"max", ">?", /* old */
"mx", ">?", /* psuedo-ansi */
"min", "<?", /* old */
"mn", "<?", /* psuedo-ansi */
};
/* Beware: these aren't '\0' terminated. */
typedef struct {
char *b; /* pointer to start of string */
char *p; /* pointer after last character */
char *e; /* pointer after end of allocated space */
} string;
#ifdef __STDC__
static void string_need (string *s, int n);
static void string_delete (string *s);
static void string_init (string *s);
static void string_clear (string *s);
static int string_empty (string *s);
static void string_append (string *p, const char *s);
static void string_appends (string *p, string *s);
static void string_appendn (string *p, const char *s, int n);
static void string_prepend (string *p, const char *s);
static void string_prepends (string *p, string *s);
static void string_prependn (string *p, const char *s, int n);
static int get_count (const char **type, int *count);
static int do_args (const char **type, string *decl);
static int do_type (const char **type, string *result);
static int do_arg (const char **type, string *result);
static int do_args (const char **type, string *decl);
static int do_cuv_prefix (const char **type, string *result, int *non_empty);
static int do_builtin_type (const char **type, string *result, int *non_empty);
static int do_template_args (const char **type, string *result);
static void munge_function_name (string *name);
static void remember_type (const char *type, int len);
#else
static void string_need ();
static void string_delete ();
static void string_init ();
static void string_clear ();
static int string_empty ();
static void string_append ();
static void string_appends ();
static void string_appendn ();
static void string_prepend ();
static void string_prepends ();
static void string_prependn ();
static int get_count ();
static int do_args ();
static int do_type ();
static int do_arg ();
static int do_args ();
static int do_cuv_prefix ();
static int do_builtin_type ();
static int do_template_args ();
static void munge_function_name ();
static void remember_type ();
#endif
int
get_simple_count (type, res)
char **type;
int *res;
{
int n = 0, success = 1;;
do
{
n *= 10;
n += **type - '0';
*type += 1;
}
while (isdigit (**type));
if (strlen (*type) < n)
{
success = 0;
}
*res = n;
return success;
}
char *
cplus_demangle (type)
const char *type;
{
string decl;
int n;
int success = 0;
int constructor = 0;
int destructor = 0;
int static_type = 0;
int const_flag = 0;
int i;
const char *p;
#ifndef LONGERNAMES
const char *premangle;
#endif
if (type == NULL || *type == '\0')
return NULL;
#ifndef nounderscore
if (*type++ != '_')
return NULL;
#endif
p = type;
while (*p != '\0' && !(*p == '_' && p[1] == '_'))
p++;
if (*p == '\0')
{
/* destructor */
if (type[0] == '_' && type[1] == CPLUS_MARKER && type[2] == '_')
{
destructor = 1;
p = type;
}
/* virtual table "_vt$" */
else if (type[0] == '_' && type[1] == 'v' && type[2] == 't' && type[3] == CPLUS_MARKER)
{
int n = strlen (type + 4) + 14 + 1;
char *tem = (char *) xmalloc (n);
strcpy (tem, type + 4);
strcat (tem, " virtual table");
return tem;
}
/* static data member */
el